package com.gitee.candy.configer.aspect;

import com.gitee.candy.configer.customInterface.HandlingTime;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.PriorityOrdered;
import org.springframework.util.StringUtils;

/**
 * <p>
 * 日志切面
 * 开启
 * 根据logging.enable的值（默认为true）将HandlingTimeInterceptor拦截器添加到SpringMVC容器中
 * <p>
 * 注解EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
 * proxyTargetClass ：true——使用CGLIB基于类创建代理；false——使用java接口创建代理
 * exposeProxy ：是否通过aop框架暴露该代理对象，aopContext能够访问.
 * </p>
 *
 * @author ：suyanlong
 * @date ：Created in 2020/11/10 16:15
 * @description：
 * @version: 1.0
 */
@Aspect
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
@Configuration
@ConditionalOnProperty(prefix = "logging", name = "enable",
        havingValue = "true", matchIfMissing = true)
public class LoggingAutoConfiguration implements PriorityOrdered {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Around("@annotation(com.gitee.candy.configer.customInterface.HandlingTime) && @annotation(handlingTime) ")
    public Object isOpen(ProceedingJoinPoint thisJoinPoint, HandlingTime handlingTime)
            throws Throwable {
        //执行方法名称
        String taskName = thisJoinPoint.getSignature()
                .toString().substring(
                        thisJoinPoint.getSignature()
                                .toString().indexOf(" "),
                        thisJoinPoint.getSignature().toString().indexOf("("));
        taskName = taskName.trim();
        long startTime = System.currentTimeMillis();
        Object result = thisJoinPoint.proceed();
        String classType = thisJoinPoint.getTarget().getClass().getName();
        Class<?> clazz = Class.forName(classType);
        String className = clazz.getName();
        String classSimpleName = clazz.getSimpleName();
        String methodName = thisJoinPoint.getSignature().getName();
        if (StringUtils.isEmpty(handlingTime.value()))
            logger.debug("调用{}（简名{}）类的{}方法执行时间：{}ms", className, classSimpleName, methodName, (System.currentTimeMillis() - startTime));
        else
            logger.debug("调用{}（简名{}）类的{}({})方法执行时间：{}ms", className, classSimpleName, methodName, handlingTime.value(), (System.currentTimeMillis() - startTime));

        return result;
    }

    @Override
    public int getOrder() {
        //保证事务等切面先执行
        return Integer.MAX_VALUE;
    }
}
